package com.heima.comment.service.impl;

import com.alibaba.fastjson.JSON;
import com.heima.apis.ariticle.IArticleClient;
import com.heima.apis.use.IUseClient;
import com.heima.comment.pojos.ApComment;
import com.heima.comment.pojos.ApCommentLike;
import com.heima.comment.service.CommentService;
import com.heima.comment.util.ThreadLocalUtil;
import com.heima.comment.vo.CommentVo;
import com.heima.common.constants.WemediaConstants;
import com.heima.common.redis.CacheService;
import com.heima.model.article.pojos.ApArticle;
import com.heima.model.comment.dtos.CommentDto;
import com.heima.model.comment.dtos.CommentLikeDto;
import com.heima.model.comment.dtos.CommentSaveDto;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.user.pojos.ApUser;
import com.heima.utils.common.SensitiveWordUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class CommentServiceImpl implements CommentService {


    @Autowired
    private IUseClient iUseClient;

    @Autowired
    private IArticleClient iArticleClient;


    @Autowired
    private MongoTemplate mongoTemplate;


    @Autowired
    private CacheService cacheService;


    @Override
    public ResponseResult saveComment(CommentSaveDto dto) {

        if (!auditText(dto.getContent())) {
            //审核未通过
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }


        ResponseResult userResponseResult = iUseClient.findById(ThreadLocalUtil.get());
        if (userResponseResult.getCode()!=200 || userResponseResult.getData()==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.AP_USER_DATA_NOT_EXIST);
        }

        Object userJsonObject = userResponseResult.getData();
        String userJson = JSON.toJSONString(userJsonObject);
        ApUser user= JSON.parseObject(userJson,ApUser.class);

        ResponseResult apArticleResponseResult = iArticleClient.findById(dto.getArticleId());
        if (apArticleResponseResult.getCode()!=200 || apArticleResponseResult.getData()==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST);
        }

        Object articleJsonObject = apArticleResponseResult.getData();
        String articleJson = JSON.toJSONString(articleJsonObject);
        ApArticle article = JSON.parseObject(articleJson,ApArticle.class);



        ApComment apComment = new ApComment();
        apComment.setAuthorId(user.getId());
        apComment.setAuthorName(user.getName());
        apComment.setArticleId(dto.getArticleId());
        apComment.setChannelId(article.getChannelId());
        apComment.setContent(dto.getContent());
        apComment.setImage(user.getImage());
        apComment.setCreatedTime(new Date());
        apComment.setUpdatedTime(new Date());
        //保存到MongoDB
        mongoTemplate.save(apComment);


        return ResponseResult.okResult("评论成功");
    }

    @Override
    @Transactional
    public ResponseResult like(CommentLikeDto dto) {
        Query queryApComment = Query.query(Criteria.where("_id").is(dto.getCommentId()));
        ApComment apCommentInDb= mongoTemplate.findOne(queryApComment, ApComment.class);
        if (dto.getOperation()==0){
            apCommentInDb.setLikes(apCommentInDb.getLikes()-1);
        } else if (dto.getOperation() == 1) {
            apCommentInDb.setLikes(apCommentInDb.getLikes()+1);
        }
        //更新更新时间
        apCommentInDb.setUpdatedTime(new Date());

        Query queryApCommentLike = Query.query(Criteria.where("authorId")
                .is(ThreadLocalUtil.get())
                .and("commentId")
                .is(dto.getCommentId()));

        ApCommentLike apCommentLikeInDb= mongoTemplate.findOne(queryApCommentLike, ApCommentLike.class);


        if(apCommentLikeInDb==null){
            ApCommentLike apCommentLike = new ApCommentLike();
            apCommentLike.setCommentId(dto.getCommentId());
            apCommentLike.setAuthorId(ThreadLocalUtil.get());
            apCommentLike.setOperation(Integer.valueOf(dto.getOperation()));
        }else {
            apCommentLikeInDb.setOperation(Integer.valueOf(dto.getOperation()));
        }
        HashMap hashMap = new HashMap();
        hashMap.put("likes",apCommentInDb.getLikes());


        return ResponseResult.okResult(hashMap);
    }

    @Override
    public ResponseResult findByArticleId(CommentDto dto) {
        //文章评论查询
        Query articleQuery = Query.query(Criteria.where("articleId").is(dto.getArticleId()).and("updatedTime").lt(dto.getMinDate()))
                .with(Sort.by(Sort.Direction.DESC,"updatedTime"))
                .limit(10);
        List<ApComment> apComments = mongoTemplate.find(articleQuery, ApComment.class);

        //用户是否喜欢评论
        List<CommentVo> commentVoList = apComments.stream().map(apComment -> {

            Query queryApCommentLike = Query.query(Criteria.where("authorId")
                    .is(ThreadLocalUtil.get())
                    .and("commentId")
                    .is(apComment.getId()));
            ApCommentLike apCommentLike = mongoTemplate.findOne(queryApCommentLike, ApCommentLike.class);

            CommentVo commentVo = new CommentVo();
            BeanUtils.copyProperties(apComment, commentVo);
            if (apCommentLike == null) {
                commentVo.setOperation(0);
            } else {
                commentVo.setOperation(apCommentLike.getOperation());
            }
            return commentVo;

        }).collect(Collectors.toList());


        return ResponseResult.okResult(commentVoList);
    }

    private boolean auditText(String text){

        Set<String> wmSensitiveset = cacheService.setMembers(WemediaConstants.CATCH_KEY_SENSITIVE);
        SensitiveWordUtil.initMap(wmSensitiveset);
        Map<String, Integer> stringIntegerMap = SensitiveWordUtil.matchWords(text);
        if (!stringIntegerMap.isEmpty()){
            return false;
        }

        return true;
    }
}
